home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 44
/
Amiga Format CD44 (1999-08-26)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-10].iso
/
-in_the_mag-
/
basics
/
blitz
/
hookfunc.lha
/
hookfunc.bb2
next >
Wrap
Text File
|
1998-12-22
|
7KB
|
140 lines
; Description: How to use hooks in Blitz. This one is an example for the ASL
; screenmode requester and it works. Working parts by Paul "Mildred"
; West.
; You need amigalibsii.res resident.
;
; Note that some things aren't explained fully (i.e. the tags
; for the screenmode requester). You should look at the Autodocs
; for these.
; Type: SYSTEM
; These defines should be in amigalibsii.res, but they appear not to be
#DTAG_DISP=$80000000
#DTAG_DIMS=$80001000
#DTAG_MNTR=$80002000
#DTAG_NAME=$80003000
; The initial values for the width and height when opening the screenmode
; requester (silly really, as we won't see them - see later in code)
PrefDisplayWidth.w=320
PrefDisplayHeight.w=240
DEFTYPE.Hook myhook ; The hook for ASL tag as &myhook
myhook\h_Entry=?hook ; Set address of hook stub which sorts out registers and calls Blitz function
myhook\h_SubEntry = ?hook_jump ; Set address of Blitz function. NB That you must have a label directly before the function
PutReg a5,myhook\h_Data ; Store the global variables base
; Set up some tags for the ASL screenmode requester
Dim SMRtags.TagItem(18)
SMRtags(0)\ti_Tag=#ASLSM_InitialLeftEdge,160 ; Initial left edge of requester
SMRtags(1)\ti_Tag=#ASLSM_InitialTopEdge,0 ; Initial top edge of requester
SMRtags(2)\ti_Tag=#ASLSM_InitialWidth,300 ; Initial width of requester
SMRtags(3)\ti_Tag=#ASLSM_InitialHeight,600 ; Initial height of requester
SMRtags(4)\ti_Tag=#ASLSM_InitialDisplayID,$21000 ; Initial screenmode (if present, PAL:Lowres)
SMRtags(5)\ti_Tag=#ASLSM_InitialDisplayDepth,8 ; Initial depth of screen (in bitplanes/bits per pixel)
SMRtags(6)\ti_Tag=#ASLSM_InitialDisplayWidth,PrefDisplayWidth ; Initial width of desired screen
SMRtags(7)\ti_Tag=#ASLSM_InitialDisplayHeight,PrefDisplayHeight ; Initial height of desired screen
SMRtags(8)\ti_Tag=#ASLSM_InitialOverscanType,2 ; Initial overscan type in cycle gadget (2 = #OSCAN_STANDARD)
SMRtags(9)\ti_Tag=#ASLSM_InitialInfoOpened,1 ; Set information box to open
SMRtags(10)\ti_Tag=#ASLSM_InitialInfoLeftEdge,350 ; Initial left edge of info box
SMRtags(11)\ti_Tag=#ASLSM_InitialInfoTopEdge,50 ; Initial top edge of info box
SMRtags(12)\ti_Tag=#ASLSM_DoDepth,0 ; Don't show depth requester to user
SMRtags(13)\ti_Tag=#ASLSM_DoOverscanType,1 ; Show overscan cycle gadget to user
SMRtags(14)\ti_Tag=#ASLSM_DoWidth,1 ; Show width gadget to user
SMRtags(15)\ti_Tag=#ASLSM_DoHeight,1 ; Show height gadget to user
SMRtags(16)\ti_Tag=#ASLSM_FilterFunc,&myhook ; Set hook for this function
SMRtags(17)\ti_Tag=#TAG_END ; End of tag list
; Initialise and allocate a requester for the screenmode
*sreq.ScreenModeRequester=0
*sreq=AllocAslRequest_(#ASL_ScreenModeRequest,&SMRtags(0)\ti_Tag)
; Display the requester
ok.b=AslRequest_(*sreq,&SMRtags(0)\ti_Tag)
; If the return value was not 0 (therefore a success)
If ok<>0
; Display the returned values in the structure allocated earlier
; and wait for 3 seconds
NPrint *sreq\sm_DisplayID
NPrint *sreq\sm_DisplayWidth
NPrint *sreq\sm_DisplayHeight
Delay_ 150
EndIf
If (*sreq) Then FreeAslRequest_(*sreq) ; If the screenmode allocation succeeded, then free theallocated memory
;*************************************************************************
; This is the Function that the hook will call. Put the label before
; the Statement/Function you want To jump To. Note that you need to put
; Runnerrsoff and Runerrson around the statement or function.
;
; In this implementation, the ASL screenmode requester uses a hook to decide
; which screenmodes to display in the selection list. This function returns
; true for ASL to display the screenmode and false to not display the screenmode.
; The hook (and therefore this function) are called for every screenmode that
; ASL screenmode requester finds.
Runerrsoff
hook_jump:
Function.l hook{*dahook.Hook, modeID.l, *smr.ScreenModeRequester}
DEFTYPE.DisplayInfo DisInfoBuf ; Buffer to receive information about mode display
DEFTYPE.DimensionInfo DimInfoBuf ; Buffer to receive information about mode dimensions
DEFTYPE.MonitorInfo MonInfoBuf ; Buffer to receive information about monitor (driver)
DEFTYPE.NameInfo NamInfoBuf ; Buffer to receive information about mode name
; Gets a handle to a record of display information for the screenmode in question
IDhandle.l=FindDisplayInfo_(modeID)
; Fill in the various buffers about this screenmode, using the newly
; gotten handle
GetDisplayInfoData_ IDhandle,&DisInfoBuf,SizeOf.DisplayInfo,#DTAG_DISP,0
GetDisplayInfoData_ IDhandle,&DimInfoBuf,SizeOf.DimensionInfo,#DTAG_DIMS,0
GetDisplayInfoData_ IDhandle,&MonInfoBuf,SizeOf.MonitorInfo,#DTAG_MNTR,0
GetDisplayInfoData_ IDhandle,&NamInfoBuf,SizeOf.NameInfo,#DTAG_NAME,0
; Do tests. True=Mode is valid, False=mode is invalid. In these test, any mode
; with a maximum horizontal width of less than 400 is rejected (i.e. PAL and
; NTSC Lowres modes)
If DimInfoBuf\Nominal\MaxX < 400
Function Return False
Else
Function Return True
End If
End Function
Runerrson
;*************************************************************************
;*************************************************************************
Goto HookSkip ; This is done so that hook code does not get
; executed out of place
; Code for calling the higher level hook functions. This piece of code is used
; for all hooks. Basically it puts whats in A0 (usually the *hook structure) into
; D0, A1 into D1 and A2 into D2. What this means is that within your high level
; function, you should have three parameters. These parameters must match up with
; what the Autodocs say will be passed in the address registers (given that they
; are put into the data registers). Remember that in Blitz, the parameters
; are in order of data register D0 first parameter, and so on.
; This hook will also return a value in D), which is the value returned by the
; high level function. Some hook applications may need this, others may not.
hook: MOVEM.l d1-d7/a0-a6,-(a7) ; Save registers to stack (NOT D0!!!)
MOVE.l a0,d0 ; These three moves put the hook parameters
MOVE.l a1,d1 ; (which are in A0-A2) into the data registers,
MOVE.l a2,d2 ; so that the Blitz function can access them
MOVEA.l 16(a0),a5 ; Restore the global variable base
MOVEA.l 12(a0),a3 ; Get the address pointed to by the h_SubEntry field of the Hook structure
LEA.l 6(a3),a3 ; Get the address to jump to (adress of high level function)
JSR (a3) ; Go do it!!
; The value is returned in d0 from the function. As this is where
; we want it, nothing is done, and the hook returns.
MOVEM.l (a7)+,d1-d7/a0-a6 ; Restore registers from stack (NOT D0, we want to keep the return value)
RTS
HookSkip
End